// ------------------------------------------------------------------------
// 版权信息
// 版权归重庆虫儿飞科技有限公司所有。
// 所有权利保留。
// 官方网站：https://netokit.com
// 许可证信息
// Neto.Kit 项目主要遵循 MIT 许可证和 Apache 许可证（版本 2.0）进行分发和使用。
// 许可证的完整文本可以在源代码树根目录中的 LICENSE-APACHE 和 LICENSE-MIT 文件中找到。
// 
// 使用条款
// 使用本代码应遵守相关法律法规和许可证的要求。
// 
// 免责声明
// 对于因使用本代码而产生的任何直接、间接、偶然、特殊或后果性损害，我们不承担任何责任。
// 
// 其他重要信息
// Neto.Kit 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。
// 有关 Neto.Kit 项目的其他详细信息，请参阅位于源代码树根目录中的 COPYRIGHT 和 DISCLAIMER 文件。
// 
// 更多信息
// 请访问 https://netokit.com 获取更多关于 Neto.Kit 项目的许可证和版权信息。
// ------------------------------------------------------------------------

namespace Neto;

/// <summary>
///     全局静态
/// </summary>
public static class AppX
{
    /// <summary>
    ///     获取上传文件的文件夹
    /// </summary>
    /// <returns></returns>
    public static string GetUploadDefaultFloder()
    {
        return WebUpload.GetFileUploadFloder();
    }

    /// <summary>
    ///     获取上传文件完整路径
    /// </summary>
    /// <param name="fileRelativePath">文件相对路径（例如：/20220101/xxxx.png或 abc\abc\11.png）</param>
    /// <returns></returns>
    public static string? GetUploadFileFullPath(string fileRelativePath)
    {
        var floder = GetUploadDefaultFloder();
        //拼接完整文件路径

        //获取完整的文件路径
        //path2 不能以 \ 和 / 开头的字符串， 如果是这个字符串开头的，则返回 path2 。
        var filepath = Path.Combine(floder, $"{fileRelativePath.Replace("/", "\\").TrimStart("\\")}");

        return !File.Exists(filepath) ? null : filepath;
    }

    /// <summary>
    ///     获取上传文件完整路径
    /// </summary>
    /// <param name="fileRelativePath">文件相对路径（例如：/20220101/xxxx.png或 abc\abc\11.png）</param>
    /// <returns></returns>
    public static string? GetWwwrootUploadFileFullPath(string fileRelativePath)
    {
        var floder = App.WebHostEnvironment.WebRootPath;
        //拼接完整文件路径

        //获取完整的文件路径
        //path2 不能以 \ 和 / 开头的字符串， 如果是这个字符串开头的，则返回 path2 。
        var filepath = Path.Combine(floder, $"{fileRelativePath.Replace("/", "\\").TrimStart("\\")}");

        return !File.Exists(filepath) ? null : filepath;
    }


    /// <summary>
    ///     获取配置(默认)
    /// </summary>
    /// <typeparam name="TOptions">强类型选项类</typeparam>
    /// <param name="loadPostConfigure"></param>
    /// <param name="isNullDefaultNew">如果为空，实例化一个默认对象</param>
    /// <param name="isNewObj">是否生成新对象，防止对option修改导致bug</param>
    /// <returns>TOptions</returns>
    public static TOptions GetConfig<TOptions>(bool loadPostConfigure = false, bool isNullDefaultNew = true,
        bool isNewObj = true) where TOptions : class, new()
    {
        var path = typeof(TOptions).Name;
        if (path.EndsWith("Options")) path = path.ReplaceLast("Options", "");
        var option = App.GetConfig<TOptions>(path, true);
        if (option == null && isNullDefaultNew) option = new TOptions();
        //如果是新对象，则先进行序列化，然后在进行反序列化
        if (isNewObj) return option.ExpressionClone();
        return option;
    }

    /// <summary>
    ///     获取访问信息
    /// </summary>
    /// <returns></returns>
    public static WebHttpInfo GetWebInfo()
    {
        return App.HttpContext?.GetWebInfo();
    }

    /// <summary>
    ///     获取访问信息
    /// </summary>
    /// <returns></returns>
    public static StringBuilder GetWebInfoToString(StringBuilder stringBuilder = null)
    {
        return App.HttpContext.GetWebInfoToString(stringBuilder);
    }

    /// <summary>
    ///     线程延迟调用
    /// </summary>
    /// <param name="action">方法</param>
    /// <param name="millisecondsDelay">延迟时间，默认1000毫秒，最小10毫秒</param>
    /// <param name="cancellationToken">取消令牌</param>
    public static void TaskDelay(Action action, int millisecondsDelay = 1000,
        CancellationToken cancellationToken = default)
    {
        Task.Run(async () =>
        {
            // 限制最小延迟时间为10毫秒
            if (millisecondsDelay <= 10) millisecondsDelay = 10;
            using var delayTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);

            var delayTask = Task.Delay(millisecondsDelay, delayTokenSource.Token);
            delayTokenSource.Token.ThrowIfCancellationRequested();

            // 确保在延迟任务完成后执行操作
            await delayTask.ConfigureAwait(false);

            action();
        }, cancellationToken);
    }

    #region Http

    /// <summary>
    ///     获取HttpClient
    /// </summary>
    /// <param name="clientName"></param>
    /// <param name="timeOut"></param>
    /// <returns></returns>
    public static HttpClient GetHttpClient(string clientName, TimeSpan? timeOut)
    {
        var clientFactory = App.GetService<IHttpClientFactory>(App.RootServices);

        var httpClient = string.IsNullOrWhiteSpace(clientName)
            ? clientFactory.CreateClient()
            : clientFactory.CreateClient(clientName);
        if (timeOut.HasValue) httpClient.Timeout = timeOut.Value;

        return httpClient;
    }

    #endregion Http


    #region 登录信息

    /// <summary>
    ///     用户id
    /// </summary>
    public static int UserIdByInt => App.User.GetLoginUserId<int>();

    /// <summary>
    ///     用户id
    /// </summary>
    public static long UserId => App.User.GetLoginUserId<long>();

    /// <summary>
    ///     账号
    /// </summary>
    public static string? Account => App.User.GetLoginUserAccount();

    /// <summary>
    ///     昵称
    /// </summary>
    public static string? Name => App.User.GetLoginUserNick();

    /// <summary>
    ///     获取租户 Id
    /// </summary>
    public static string? TenantIdStr => App.User.GetUserValue<string>(ClaimConst.Claim_TenantId);

    /// <summary>
    ///     获取租户 Id
    /// </summary>
    public static long TenantId => App.User.GetUserValue<long>(ClaimConst.Claim_TenantId);

    /// <summary>
    ///     获取租户 Id
    /// </summary>
    public static T? GetTenantId<T>()
    {
        return App.User.GetUserValue<T>(ClaimConst.Claim_TenantId);
    }

    #endregion 登录信息

   
}